package com.vd.tbsms.process.impl;

import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.vd.tbsms.Status;
import com.vd.tbsms.parse.PropParse;
import com.vd.tbsms.process.ProcessCallBack;
import com.vd.tbsms.process.SendProcess;

public class MailSendProcess implements SendProcess {

	private static final Log log = LogFactory.getLog(MailSendProcess.class);
	private Status status = Status.INIT;
	private String errMsg;
	private ProcessCallBack callBack;
	private String senderUser;
	private String senderPasswd;
	private Integer sendPos = 0;
	private List<?> sendList;
	private String mailSubject;
	private boolean isContainTable;
	private boolean isSendFaild = false;
	private String mailContent;

	public void sendMsg(String subject, String content, List<?> list, String user, String passwd, boolean isContainTable) {

		this.senderUser = user;
		this.senderPasswd = passwd;
		this.sendList = list;
		this.mailSubject = subject;
		this.isContainTable=isContainTable;
		this.mailContent=content;
		doSend();
		log.info("sendMsg job start......");
	}

	private void doSend() {
		this.status=Status.SENDING;
		this.sendPos=0;
		Integer threadCount = Integer.valueOf(PropParse.getInstance().getValue("vd.send.threads"));
		Thread[] threadGroup = new Thread[threadCount];
		SendTask sendTask = new SendTask();
		for (int i = 0; i < threadCount; i++) {
			threadGroup[i] = new Thread(sendTask, "sendMail-Thread-" + i);
			threadGroup[i].start();
		}
		Thread afterThread = new Thread(new AfterSendTask(threadGroup), "afterSendMail-Thread");
		afterThread.start();
	}

	public void sendMsg(String subject, String content, List<?> list, String user, String passwd,
			boolean isContainTable, String attachment) {
	}

	public String getErrMsg() {
		return errMsg;
	}

	public Status getStatus() {
		return status;
	}

	@Override
	public void setCallBack(ProcessCallBack callBack) {
		this.callBack = callBack;
	}

	protected class SendTask implements Runnable {
		@SuppressWarnings("unchecked")
		@Override
		public void run() {
			log.info(Thread.currentThread().getName() + "start.....");
			boolean running = true;
			Integer sendCnts = sendList.size();
			Session session = Session.getDefaultInstance(PropParse.getInstance().getProp(), new Authenticator() {
				@Override
				protected PasswordAuthentication getPasswordAuthentication() {
					return new PasswordAuthentication(senderUser, senderPasswd);
				}
			});
			while (running) {
				Map wd = null;
				int myPos = 0;
				synchronized (sendPos) {
					if (sendPos < sendCnts) {
						log.info("send pos:" + sendPos);
						wd = (Map) sendList.get(sendPos);
						myPos = sendPos;
						sendPos++;
					} else {
						running = false;
						break;
					}
				}
				if (wd == null) {
					log.warn("发送明细为空");
					continue;
				}
				log.info(Thread.currentThread().getName() + "send [" + sendPos + "] start");
				try {
					if (callBack != null)
						callBack.updateStatus(myPos, Status.SENDING.toString());

					String content = GenMailProcess.genMailInfo(wd, mailContent, isContainTable);
					Message msg = new MimeMessage(session);
					String chnName = PropParse.getInstance().getValue("vd.send.name");
					if(chnName.isEmpty()){ 
						chnName = senderUser;
					}else{
						chnName = new String(chnName.getBytes("ISO-8859-1"), "utf-8");
					}
					InternetAddress addressFrom = new InternetAddress(senderUser
							+ PropParse.getInstance().getValue("vd.mail_suffix"),
							chnName);
					msg.setFrom(addressFrom);
					String receiptAddress = (String) wd.get("邮箱地址");
					if(receiptAddress== null || receiptAddress.isEmpty()){
						receiptAddress = (String) wd.get("邮箱");
					}
					if(receiptAddress== null || receiptAddress.isEmpty()){
						log.warn("找不到邮箱地址:"+sendPos);
					}
					if (!receiptAddress.contains("@"))
						receiptAddress += PropParse.getInstance().getValue("vd.mail_suffix");
					msg.setRecipient(Message.RecipientType.TO, new InternetAddress(receiptAddress,(String)wd.get("姓名")));
					msg.setSubject(mailSubject);
					msg.setContent(content, "text/html;charset=gb2312");
					msg.setSentDate(new Date());
					Transport.send(msg);
					if (callBack != null)
						callBack.updateStatus(myPos, Status.SUCC.toString());
				} catch (Exception e) {
					log.error("send mail Exception", e);
					if (callBack != null)
						callBack.updateStatus(myPos, Status.FAILD.toString());
					isSendFaild = true;
				}
				log.info(Thread.currentThread().getName() + "send [" + sendPos + "] end");
			}
		}
	}

	protected class AfterSendTask implements Runnable {
		private Thread[] group;

		public AfterSendTask(Thread[] group) {
			this.group = group;
		}

		@Override
		public void run() {
			log.info("AfterSendTask start....");
			for (Thread thread : group) {
				try {
					thread.join();
				} catch (InterruptedException e) {
					log.error("waitException", e);
				}
			}
			status = Status.COMP;
			String tip = "邮件发送已完成完成。";
			if (isSendFaild) {
				tip += "\n标红为发送失败,请确认";
			}
			if (callBack != null)
				callBack.tipMsg(tip);
		}

	}

}
